#ifndef LINK_MANAGER_H
#define LINK_MANAGER_H

#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/mobility-module.h"
#include "ns3/wifi-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "node_manager.h"
#include <map>
#include <vector>

namespace ns3 {

/**
 * @brief 连接类型枚举
 */
enum class ConnectionType {
  WIFI,        ///< 车辆与地面基站的WiFi连接
  SATELLITE    ///< 车辆与卫星的P2P连接
};

/**
 * @brief 连接信息结构
 */
struct ConnectionInfo {
  uint32_t nodeId;               ///< 连接目标节点的ID
  std::string nodeType;          ///< 节点类型（"GroundStation"或"Satellite"）
  Ipv4InterfaceContainer ipIfaces; ///< IP接口
  ApplicationContainer apps;      ///< 应用
  double distance;               ///< 两节点间距离
};

/**
 * @brief 链接管理器类，负责管理节点间的网络连接
 */
class LinkManager 
{
public:
  /**
   * @brief 构造函数
   */
  LinkManager();
  
  /**
   * @brief 析构函数
   */
  ~LinkManager();
  
  /**
   * @brief 初始化链接管理器
   * @param nodeManager 节点管理器引用
   * @return 初始化是否成功
   */
  bool Initialize(NodeManager& nodeManager);
  
  /**
   * @brief 设置WiFi连接（车辆与地面基站）
   * @return 设置是否成功
   */
  bool SetupWifiConnections();
  
  /**
   * @brief 设置卫星连接（车辆与卫星）
   * @return 设置是否成功
   */
  bool SetupSatelliteConnections();
  
  /**
   * @brief 分配IP地址
   * @return 分配是否成功
   */
  bool AssignIpAddresses();
  
  /**
   * @brief 设置应用程序
   */
  void SetupApplications();
  
  /**
   * @brief 获取地面基站连接信息
   * @return 地面基站连接信息映射
   */
  const std::map<uint32_t, ConnectionInfo>& GetGroundStationConnections() const;
  
  /**
   * @brief 获取卫星连接信息
   * @return 卫星连接信息映射
   */
  const std::map<uint32_t, ConnectionInfo>& GetSatelliteConnections() const;
  
  /**
   * @brief 获取车辆节点的接口
   * @param type 连接类型
   * @param nodeId 目标节点ID
   * @return 车辆节点接口
   */
  Ptr<Ipv4> GetVehicleIpv4(ConnectionType type, uint32_t nodeId) const;
  
  /**
   * @brief 获取目标节点的接口
   * @param type 连接类型
   * @param nodeId 目标节点ID
   * @return 目标节点接口
   */
  Ptr<Ipv4> GetTargetIpv4(ConnectionType type, uint32_t nodeId) const;
  
  /**
   * @brief 获取连接中的应用程序
   * @param type 连接类型
   * @param nodeId 目标节点ID
   * @return 应用程序容器
   */
  ApplicationContainer GetApplications(ConnectionType type, uint32_t nodeId) const;
  
  /**
   * @brief 获取两节点间的距离
   * @param type 连接类型
   * @param nodeId 目标节点ID
   * @return 距离（米）
   */
  double GetDistance(ConnectionType type, uint32_t nodeId) const;
  
  /**
   * @brief 重置链接管理器
   */
  void Reset();

private:
  /**
   * @brief 计算两节点间的距离
   * @param node1 节点1
   * @param node2 节点2
   * @return 距离（米）
   */
  double CalculateDistance(Ptr<Node> node1, Ptr<Node> node2) const;

private:
  const NodeManager* m_nodeManager;  ///< 节点管理器引用
  
  NetDeviceContainer m_wifiDevices;  ///< WiFi设备
  
  Ipv4AddressHelper m_wifiAddresses; ///< WiFi地址助手
  Ipv4AddressHelper m_p2pAddresses;  ///< P2P地址助手
  
  std::map<uint32_t, NetDeviceContainer> m_p2pDevices;     ///< 车辆与卫星的P2P设备
  std::map<uint32_t, ConnectionInfo> m_gsConnections;      ///< 车辆与地面基站的连接信息
  std::map<uint32_t, ConnectionInfo> m_satelliteConnections; ///< 车辆与卫星的连接信息
};

} // namespace ns3

#endif // LINK_MANAGER_H
